import React, { Component } from "react";

class DemoRef extends Component {
    titleHeader3 = React.createRef();
    render() {
        return (
            <>
                <h2 className="title" ref="titleHeader1">温馨提示</h2>
                <h2 className="title" ref={ x => this.titleHeader2 = x}>友情提示</h2>
                <h2 className="title" ref={ this.titleHeader3 }>郑重提示</h2>
            </>
        )
    };   
    componentDidMount() {
        // 第一次渲染完毕 [virtualDom 已经变为 真实Dom] 此时我们可以获取需要操作的Dom元素
        console.log(this.refs.titleHeader1); // React.StrictMode严格模式下会报错
        console.log(this.titleHeader2);
        console.log(this.titleHeader3.current);
        /**
         * 基于ref获取dom元素
         *      @1--- console.log(this.refs.titleHeader1);  // 不推荐使用
         *      @2--- ref={ x => this.titleHeader2 = x}
         *          + x是函数的形参，存储的就是当前DOM元素
         *          + 然后将获取的DOM元素直接挂载到实例的某个属性上
         *      @3--- titleHeader3 = React.createRef()
         *          + 基于React.createRef()创建一个ref对象
         * 原理： 在render渲染的时候，会获取到virtualDom的ref属性
         *     @1--- 如果属性值是一个字符串，则会给this.refs添加这样一个成员，值为当前dom元素
         *     @2--- 如果属性值是一个函数，则会把函数执行，把当前dom元素传递给这个函数【x =》Dom元素】，而在函数执行的内部，我们一般会将dom元素直接挂载到实例的某个属性上 
         *     @3--- 如果属性值是一个ref对象，则会将dom元素赋值给对象的current属性
         */
    };
};

export default DemoRef;

/**
 * 受控组件：受状态管控的组件，基于修改数据/状态，让视图更新，以达到想要的效果『推荐』 
 * 非受控组件：基于ref，获取DOM元素，我们操作DOM元素以实现需求和效果 「偶尔」 
 */

/**
 * 给元素标签设置ref 目的：获取dom元素
 * 给类组件设置ref 目的：获取当前调用组件的实例【后续可以根据实例获取子组件中的相关信息】
 * 给函数组件设置ref， @1 @2 两种方法都会报错，@3方法获取到的current为null
 *      +  但是我们可以配合React.forwardRef获取函数子组件内部的dom元素
 */